package com.program.houai.controller;

import cn.hutool.http.HttpStatus;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.houbb.heaven.util.secrect.AesUtil;
import com.program.houai.entity.UserEntity;
import com.program.houai.entity.UserVipCardEntity;
import com.program.houai.entity.VipCardOrderEntity;
import com.program.houai.exception.BusinessException;
import com.program.houai.exception.ErrorType;
import com.program.houai.pay.*;
import com.program.houai.po.LoginUser;
import com.program.houai.po.VipCardOrderPO;
import com.program.houai.redis.RedisService;
import com.program.houai.service.IUserService;
import com.program.houai.service.IVipCardOrderService;
import com.program.houai.util.DateFullUtils;
import com.program.houai.util.IPUtils;
import com.program.houai.util.PageUtils;
import com.program.houai.util.R;
import com.program.houai.vo.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.MediaType;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import javax.xml.bind.JAXBException;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.net.URISyntaxException;
import java.security.GeneralSecurityException;
import java.time.LocalDateTime;
import java.util.*;

import static javax.accessibility.AccessibleRole.SEPARATOR;

/**
 * @version v1.0
 * @ProjectName: EOrder-master
 * @ClassName: OrderController
 * @Description: TODO(一句话描述该类的功能)
 * @Author: Topcheer
 * @Date: 2024/8/31 9:45
 */
@Api(tags = "我的订单")
@RestController
@RequestMapping("/app/order")
@Slf4j
@Validated
public class OrderController {

    @Autowired
    private RedisService redisService;

    @Autowired
    private IVipCardOrderService vipCardOrderService;

    @Autowired
    private IUserService userService;

    @Value("${system.file.request-url}")
    private String requestUrl;

    @Value("${vx.mchId}")
    private String mchId;

    @Value("${vx.payType}")
    private String payType;

    @Value("${vx.appId}")
    private String appId;

    @Value("${vx.mchSecret}")
    private String mchSecret;


    @ApiOperation("提交订单")
    @PostMapping(value = "/generateOrder", produces = MediaType.APPLICATION_JSON_VALUE)
    public R<String> generateSmsCode(@RequestBody @Valid SubmitOrderVO submitOrderVO, @RequestHeader("token") String token) {
        LoginUser loginUser =  redisService.getLoginValueByToken(token);
        String orderNumber = vipCardOrderService.saveVipCardOrder(submitOrderVO, loginUser.getId());
       return R.ok(orderNumber);
    }

    @ApiOperation("订单查询")
    @PostMapping(value = "/getOrderByOrderNumber", produces = MediaType.APPLICATION_JSON_VALUE)
    public R<VipCardOrderPO> generateSmsCode(@RequestBody OrderQUeryVO orderQUeryVO){
        return R.ok(vipCardOrderService.getOrderInfoByNumber(orderQUeryVO.getOrderNumber()));
    }

    @ApiOperation("我的订单列表")
    @PostMapping(value = "/getOrderList", produces = MediaType.APPLICATION_JSON_VALUE)
    public R<PageUtils<VipCardOrderPO>> generateSmsCode(@RequestBody OrderVO pageVO, @RequestHeader("token") String token){
        LoginUser loginUser =  redisService.getLoginValueByToken(token);
        IPage<VipCardOrderPO> page = new Page<>(pageVO.getPageNum(), pageVO.getPageSize());
        page = vipCardOrderService.getOrderListByUserId(page,loginUser.getId(),pageVO.getTxnStatus());
        for (VipCardOrderPO  vipCardOrderPO: page.getRecords()){
            BigDecimal divisor = BigDecimal.valueOf(100);
            BigDecimal dividend = BigDecimal.valueOf( vipCardOrderPO.getPrice());
            BigDecimal orderPrice = dividend.divide(divisor, 2, RoundingMode.HALF_UP);
            vipCardOrderPO.setOrderPrice(orderPrice.toString());
            vipCardOrderPO.setUrl(requestUrl+"static/buyVip/logo/"+vipCardOrderPO.getLevel()+".png");
            BigDecimal dividend1 = BigDecimal.valueOf( vipCardOrderPO.getTotalPrice());
            BigDecimal totalPrice = dividend1.divide(divisor, 2, RoundingMode.HALF_UP);
            vipCardOrderPO.setAmountPrice(totalPrice.toString());

        }
        return R.ok(new PageUtils(page));
    }



    @ApiOperation("删除订单按主键删除")
    @PostMapping(value = "/deleteOrderById", produces = MediaType.APPLICATION_JSON_VALUE)
    public R<Boolean> deleteOrder(@RequestBody BaseVO baseVO,@RequestHeader("token") String token){

        return R.ok(vipCardOrderService.removeById(baseVO.getId()));
    }


    /**
     * 微信预支付
     * @return 信息提示
     */
   @PostMapping("/prePay")
   @ApiOperation("微信预支付")
    public R wxPay(@RequestBody OrderQUeryVO param,@RequestHeader("token") String token,HttpServletRequest request) throws Exception {
       VipCardOrderPO vipCardOrderPO = vipCardOrderService.getOrderInfoByNumber(param.getOrderNumber());
       String clientIP = IPUtils.getClientIP(request);
       LoginUser loginUser = redisService.getLoginValueByToken(token);
       UserEntity userEntity = userService.getById(loginUser.getId());
       PaySignReq paySignReq = new PaySignReq();
       paySignReq.setService(payType);
       paySignReq.setMch_id(mchId);
       paySignReq.setOut_trade_no(param.getOrderNumber());
       paySignReq.setBody(vipCardOrderPO.getVipName());
       paySignReq.setSub_appid(appId);
       paySignReq.setSub_openid(userEntity.getOpenId());
       paySignReq.setMch_create_ip(clientIP);
       paySignReq.setTotal_fee(vipCardOrderPO.getTotalPrice());
       paySignReq.setIs_raw("1");
       paySignReq.setNotify_url("https://app-api.chanson.ltd/partner-xg/app/order/payNotify");
       paySignReq.setNonce_str(UUID.randomUUID().toString().replaceAll("-",""));

       SortedMap<String, Object> map = new TreeMap<>();
       map.put("service",paySignReq.getService());
       map.put("mch_id",paySignReq.getMch_id());
       map.put("out_trade_no",paySignReq.getOut_trade_no());
       map.put("sub_openid",paySignReq.getSub_openid());
       map.put("sub_appid",paySignReq.getSub_appid());
       map.put("body",paySignReq.getBody());
       map.put("total_fee",paySignReq.getTotal_fee());
       map.put("mch_create_ip",paySignReq.getMch_create_ip());
       map.put("notify_url",paySignReq.getNotify_url());
       map.put("nonce_str",paySignReq.getNonce_str());
       map.put("is_raw",paySignReq.getIs_raw());
       String  signMapStr = MD5Util.getSign(map,mchSecret);
       paySignReq.setSign(signMapStr);
       String url = "https://pay.wepayez.com/pay/gateway";
       String xml = XmlUtil.convertToXml(paySignReq);
       log.info("========="+xml);
       String  result =   HttpClientUtil.postXml(url,xml);
       log.info(result);
       PaySignRsp paySignRsp = XmlUtil.fromXml(result,PaySignRsp.class);
       if (!paySignRsp.getStatus().equals("0") && !paySignRsp.getResult_code().equals("0")){
           throw new BusinessException(ErrorType.BIZ_ERROR,"签名错误请联系系统管理员！");
       }
       paySignRsp.setPrepay_id("prepay_id="+paySignRsp.getToken_id());
       long currentSeconds = System.currentTimeMillis() / 1000;
       paySignRsp.setTimeStamp(currentSeconds+"");
       return R.ok(paySignRsp);
   }


    public static void main(String[] args) throws Exception {
        PaySignReq paySignReq = new PaySignReq();
        paySignReq.setService("pay.weixin.jspay");
        paySignReq.setMch_id("104560000173");
        paySignReq.setOut_trade_no("2024091500011");
        paySignReq.setBody("1234567");
        paySignReq.setSub_appid("wxc2b14b9bb7cc10d0");
        paySignReq.setSub_openid("obIt-7SaWb-OjrZl9kel3ukZNgkA");
        paySignReq.setMch_create_ip("127.0.0.1");
        paySignReq.setTotal_fee(1);
        paySignReq.setNotify_url("https://app-api.chanson.ltd/partner-xg/app/order/payNotify");
        paySignReq.setNonce_str(UUID.randomUUID().toString().replaceAll("-",""));

        SortedMap<String, Object> map = new TreeMap<>();
        map.put("service",paySignReq.getService());
        map.put("mch_id",paySignReq.getMch_id());
        map.put("out_trade_no",paySignReq.getOut_trade_no());
        map.put("sub_openid","obIt-7SaWb-OjrZl9kel3ukZNgkA");
        map.put("sub_appid","wxc2b14b9bb7cc10d0");
        map.put("body",paySignReq.getBody());
        map.put("total_fee",paySignReq.getTotal_fee());
        map.put("mch_create_ip",paySignReq.getMch_create_ip());
        map.put("notify_url",paySignReq.getNotify_url());
        map.put("nonce_str",paySignReq.getNonce_str());
        String  signMapStr = MD5Util.getSign(map,"516891a743db00fb1440af1742b87ca2");
        paySignReq.setSign(signMapStr);
        String url = "https://pay.wepayez.com/pay/gateway";
        String xml = XmlUtil.convertToXml(paySignReq);
        String  result =   HttpClientUtil.postXml(url,xml);
        System.out.println(result);
   }

    /**
     * 支付成功回调
     * @param request request
     * @return map
     */

    @PostMapping("/payNotify")
    @ApiOperation("微信回调")
    public R<Boolean> payNotify(HttpServletRequest request) throws JAXBException {
        log.info("微信支付成功回调进来了");
        //获取报文
        String body = getRequestBody(request);
        log.info(body);
        PayResult payResult = XmlUtil.fromXml(body,PayResult.class);
        if (payResult.getPay_result().equals("0") && payResult.getResult_code().equals("0")){
            //支付成功
            String  orderNumber = payResult.getOut_trade_no();
            vipCardOrderService.payBack(orderNumber,payResult);
        }else{
            log.info("支付回调失败");
        }
        return R.ok();
    }


    public String getRequestBody(HttpServletRequest request) {
        StringBuffer sb = new StringBuffer();
        try (ServletInputStream inputStream = request.getInputStream();
             BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
        ) {
            String line;
            while ((line = reader.readLine()) != null) {
                sb.append(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return sb.toString();

    }

}
